package com.kdzy.lshy.socity_server.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import com.hazelcast.core.IFunction;
import com.kdzy.lshy.socity_server.common.Constants;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.kdzy.lshy.socity_server.common.DateUtil;
import com.kdzy.lshy.socity_server.common.ExceptionDetailMessage;
import com.kdzy.lshy.socity_server.common.ResultMap;
import com.kdzy.lshy.socity_server.repository.BaseDao;

import redis.clients.jedis.Jedis;

/**
 * 居住证
 * 
 * @author zl 2018年7月20日 上午10:11:14
 *
 */
@Service
@Transactional(rollbackFor = { Exception.class })  
public class ResidencePermitService extends BaseService {

	private static final Logger logger = LoggerFactory.getLogger(ResidencePermitService.class);

	@Resource
	private BaseDao baseDao;
	
	/**
	 * 用户上传状态检测,是否可以上传
	 * 
	 * @author zl 2018年7月23日 下午8:35:52
	 * @param param
	 * @param request
	 * @return 返回值说明: 0 参数格式有误	1 参数为空 	2systoken过期 	3systoken不一致
	 *         4已有记录,允许更新,返回记录的创建时间	5无记录则允许上传		6已上传成功,不允许上传		7系统异常
	 */
	public Object uploadMaterialTest(String param, HttpServletRequest request) {
		
		if (StringUtils.isNoneBlank(StringUtils.trim(param))) {
			JSONObject jsonObject = null;
			try {
				jsonObject = JSON.parseObject(param);
			} catch (JSONException e) {
				return ResultMap.creatReault("0", "fail", "参数格式有误");
			}
			
			String dweller_id = (String) jsonObject.get("dweller_id");// 居民ID
			String bizz_id = (String) jsonObject.get("bizz_id");// 业务ID
			Integer version = (Integer) jsonObject.get("version"); // 数据版本 0:测试 1:生产
			Integer visit_plat = (Integer) jsonObject.get("visit_plat"); // 访问平台 0网页 1一体机 2小程序 3其他
			Integer visit_type = (Integer) jsonObject.get("visit_type"); // 访问类型 0测试 1生产
			Integer is_used = (Integer) jsonObject.get("is_used"); // 是否失效 0:有效 1:无效
			
			// 是否登录
			String systoken = (String) jsonObject.get("systoken"); // 当visit_plat= 0时(全局token)
			if (null == visit_plat) {
				return ResultMap.creatReault("1", "fail", "访问平台为空");
			}
			if (0 == visit_plat && null == systoken && "".equals(systoken)) {// 当visit_plat=0时(全局token)不可为空
				return ResultMap.creatReault("1", "fail", "全局token为空");
			}
			if (0 == visit_plat && null != systoken && !"".equals(systoken)) {
				if (StringUtils.isNoneBlank(StringUtils.trim(systoken))) {
					String dwellerIdcard = null;
					if (visit_plat == 0) { // 网页端

						// 根据身份证从redis中获取token
						Jedis jedis = new Jedis("140.143.210.101", 6379);
						jedis.auth("q1w2e3r4t5");

						List<String> infoList = jedis.hmget(systoken,"systoken", "dwellerIdcard", "dwellerId");
						String systokenRedis = null;
						if (infoList != null && infoList.size() > 0) {
							systokenRedis = infoList.get(0); // token
							dwellerIdcard = infoList.get(1); // 居民身份证号
							dweller_id = infoList.get(2); // 居民唯一标识
						}

						// 查看token是否过期
						if (StringUtils.isBlank(systokenRedis)) { // 重新登录，弹出登录框
							logger.info("进入ResidencePermitService.uploadMaterialTest()方法.错误原因:全局systoken过期,需要重新获取systoken");
							return ResultMap.creatReault("2", "fail","systoken过期");
						}

						// token不一致
						if (!StringUtils.equals(systokenRedis, systoken)) {
							logger.info("进入ResidencePermitService.uploadMaterialTest()方法.错误原因:用户访问的token不一致");
							return ResultMap.creatReault("2", "fail","systoken不一致");
						}
					}
				}
			}

			if (null == dweller_id || "".equals(dweller_id)) {
				return ResultMap.creatReault("1", "fail", "居民ID为空");
			}
			if (null == bizz_id || "".equals(bizz_id)) {
				return ResultMap.creatReault("1", "fail", "业务ID为空");
			}
			if (null == version) {
				return ResultMap.creatReault("1", "fail", "数据版本为空");
			}
			if (null == visit_type) {
				return ResultMap.creatReault("1", "fail", "证件类型为空");
			}
			if (null == is_used) {
				return ResultMap.creatReault("1", "fail", "是否失效为空");
			}
			
			SqlRowSet row = null;
			List<Object> quick = new ArrayList<Object>();
			quick.add(dweller_id);
			quick.add(bizz_id);
			quick.add(version);
			quick.add(visit_type);
			quick.add(is_used);
			
			try {
				row = baseDao.queryForRowSet("SELECT\n" +
						"\t*\n" +
						"FROM\n" +
						"\t(\n" +
						"\t\tSELECT\n" +
						"\t\t\ta.process_id processId,\n" +
						"\t\t\ta.create_time quickCreateTime,\n" +
						"\t\t\ta.res_type res_type\n" +
						"\t\tFROM\n" +
						"\t\t\tsocity_quick a\n" +
						"\t\tINNER JOIN (\n" +
						"\t\t\tSELECT\n" +
						"\t\t\t\tprocess_id,\n" +
						"\t\t\t\tmax(res_type) res_type\n" +
						"\t\t\tFROM\n" +
						"\t\t\t\tsocity_quick\n" +
						"\t\t\tWHERE\n" +
						"\t\t\t\tdweller_id = ?\n" +
						"\t\t\tAND bizz_id = ?\n" +
						"\t\t\tAND version = ?\n" +
						"\t\t\tAND visit_type = ?\n" +
						"\t\t\tAND is_used = ?\n" +
						"\t\t\tGROUP BY\n" +
						"\t\t\t\tprocess_id\n" +
						"\t\t) b ON a.process_id = b.process_id\n" +
						"\t\tAND a.res_type = b.res_type\n" +
						"\t\tORDER BY\n" +
						"\t\t\ta.process_id\n" +
						"\t) aa\n" +
						"ORDER BY\n" +
						"\taa.quickCreateTime DESC,\n" +
						"\taa.res_type ASC",quick.toArray());
			} catch (Exception e) {
				logger.info("进入ResidencePermitService.uploadMaterial()方法.错误原因:"+ ExceptionDetailMessage.getExceptionDetail(e));
				return ResultMap.creatReault("7", "fail", "系统异常");
			}
			if (row.next()) {// 有记录
				String processId = row.getString("processId");// 流程唯一标识
				String quickCreateTime = row.getString("quickCreateTime");// 流程唯一标识，流程创建时间
				Integer res_type = row.getInt("res_type");// 处理结果：1提交材料 2资料有误 3资料正确 4发送上门短信通知 5上门审核后失败（不在家） 6上门审核后成功 7已发放 8上门审核后失败（在家）
				// 根据状态返回提示信息
				if (null != res_type) {
					switch (res_type) {
						case 2 :// 允许更新
							LinkedHashMap<Object, Object> map = ResultMap.creatReault("4", "info", "允许更新");
							map.put("processId", processId);
							map.put("quickCreateTime", quickCreateTime);
							return map;
						case 1 :// 不允许再传
						case 3 : // 资料正确
						case 4 : // 发送上门短信通知
						case 5 : // 上门审核后失败（不在家）
						case 6 : // 上门审核后成功
							return ResultMap.creatReault("6", "info", "不允许上传");
						case 8 : // 上门审核后失败（在家）
						case 7 : // 已发放
						default :// 无记录则允许上传
							return ResultMap.creatReault("5", "info", "允许上传");
					}
				}
			}
			// 无记录则允许上传
			return ResultMap.creatReault("5", "info", "允许上传");
		} else {
			return ResultMap.creatReault("1", "fail", "参数为空");
		}
	}

	/**
	 * 上传资料
	 * 
	 * @author zl 2018年7月20日 上午10:14:47
	 * @param param
	 * @param request
	 * @return 返回值说明 	0 参数格式有误	1参数为空	2systoken过期		3systoken不一致	4已上传成功,不允许上传		5您传入的部门下没有获取到员工id,无法进行任务分配	6插入记录失败	7系统异常	8数据插入成功	9传入的数据没有全部更新记录成功	10数据更新成功
	 */
	public Object uploadMaterial(String param, HttpServletRequest request) {

		if (StringUtils.isNoneBlank(StringUtils.trim(param))) {
			// 解析param
			JSONObject jsonObject = null;
			try {
				jsonObject = JSON.parseObject(param);
			} catch (JSONException e) {
				return ResultMap.creatReault("0", "fail", "参数格式有误");
			}
			
			String dep_id = (String) jsonObject.get("dep_id"); // 部门ID
			
			Long stamp = (Long) jsonObject.get("stamp"); // 时间戳
			Integer version = (Integer) jsonObject.get("version"); // 数据版本 0:测试 1:生产
			Integer visit_plat = (Integer) jsonObject.get("visit_plat"); // 访问平台 0网页 1一体机 2小程序 3其他
			Integer visit_type = (Integer) jsonObject.get("visit_type"); // 访问类型 0测试 1生产
			Integer is_used = (Integer) jsonObject.get("is_used"); // 是否失效 0:有效 1:无效
			
			
			String dweller_id = (String) jsonObject.get("dweller_id");//居民ID
			String bizz_id = (String) jsonObject.get("bizz_id");//业务ID
			Integer res_type_quick = (Integer) jsonObject.get("res_type_quick"); // 处理结果：1:提交材料 2:资料有误 3:资料正确 4:发送上门短信通知 5:上门审核后失败（不在家） 6:上门审核后成功 7:已发放 8:上门审核后失败（在家）
			String res_note = (String) jsonObject.get("res_note");// 办事结果备注：失败时告知原因
			String sq_create_time = (String) jsonObject.get("processId"); // 社区直通业务（唯一表示该业务）
			String quickCreateTime = (String) jsonObject.get("quickCreateTime"); // 流程唯一标识，流程创建时间

			JSONArray resTypeArray = jsonObject.getJSONArray("resouce");//处理结果：1提交材料2资料有误3资料正确4发送上门短信通知5上门审核后失败（不在家） 6上门审核后成功 7已发放 8上门审核后失败（在家）
			
			// 是否登录
			String systoken = (String) jsonObject.get("systoken"); //当visit_plat = 0 时(全局token) 
			if (null == visit_plat) {
				return ResultMap.creatReault("1", "fail", "访问平台为空");
			}
			if (0 == visit_plat && null==systoken && "".equals(systoken)) {// 当visit_plat = 0 时(全局token)不可为空
				return ResultMap.creatReault("1", "fail", "全局token为空");
			}
			if (0 == visit_plat && null!=systoken && !"".equals(systoken)) {
				if (StringUtils.isNoneBlank(StringUtils.trim(systoken))) {
					String dwellerIdcard = null;
					if (visit_plat == 0) { // 网页端
						
						// 根据身份证从redis中获取token
						Jedis jedis = new Jedis("140.143.210.101", 6379);
						jedis.auth("q1w2e3r4t5");
						
						List<String> infoList = jedis.hmget(systoken, "systoken", "dwellerIdcard", "dwellerId");
						String systokenRedis = null;
						if (infoList != null && infoList.size() > 0) {
							systokenRedis = infoList.get(0); // token
							dwellerIdcard = infoList.get(1); // 居民身份证号
							dweller_id = infoList.get(2); // 居民唯一标识
						}
						
						// 查看token是否过期
						if (StringUtils.isBlank(systokenRedis)) { // 重新登录，弹出登录框
							logger.info("进入ResidencePermitService.uploadMaterial()方法.错误原因:全局systoken过期,需要重新获取systoken");
							return ResultMap.creatReault("2", "fail", "systoken过期");
						}
						
						// token不一致
						if (!StringUtils.equals(systokenRedis, systoken)) {
							logger.info("进入ResidencePermitService.uploadMaterial()方法.错误原因:用户访问的token不一致");
							return ResultMap.creatReault("3", "fail", "systoken不一致");
						}
					}
				}
			}
			
			// 入参判空
			if (null == stamp) {
				return ResultMap.creatReault("1", "fail", "时间戳为空");
			}
			if (null == version) {
				return ResultMap.creatReault("1", "fail", "数据版本为空");
			}
			if (null == visit_type) {
				return ResultMap.creatReault("1", "fail", "访问类型为空");
			}
			if (null == is_used) {
				return ResultMap.creatReault("1", "fail", "是否失效为空");
			}
			if (null == dweller_id || "".equals(dweller_id)) {
				return ResultMap.creatReault("1", "fail", "居民ID为空");
			}
			if (null == bizz_id || "".equals(bizz_id)) {
				return ResultMap.creatReault("1", "fail", "业务ID为空");
			}
			if (null == res_type_quick) {
				return ResultMap.creatReault("1", "fail", "处理结果为空");
			}
			
			String res_id = null;
			Integer res_num = null;
			Integer res_type = null;
			String res_rule = null;
			String res_url = null;
			String note = null;
			for (Object item : resTypeArray) {
				JSONObject arrObj = JSON.parseObject(item.toString());
				res_id = (String) arrObj.get("res_id");// 证件资料ID
				res_num = (Integer) arrObj.get("res_num");// 证件份数
				res_type = (Integer) arrObj.get("res_type");// 证件类型:0照片 1excel 2pdf 3doc 4zip 5其他
				res_rule = (String) arrObj.get("res_rule");// 证件规格：比如照片黑白，几寸
				res_url = (String) arrObj.get("res_url");// 证件存储地址
				note = (String) arrObj.get("note");// 备注
				
				if (null == res_id && !"".equals(res_id)) {
					return ResultMap.creatReault("1", "fail", "证件资料ID为空");
				}
				if (null == res_num) {
					return ResultMap.creatReault("1", "fail", "证件份数为空");
				}
				if (null == res_type) {
					return ResultMap.creatReault("1", "fail", "证件类型:(0照片 1excel 2pdf 3doc 4zip 5其他)为空");
				}
				if (null == res_url || "".equals(res_url)) {
					return ResultMap.creatReault("1", "fail", "证件存储地址为空");
				}
				if (null == note && !"".equals(note)) {
					return ResultMap.creatReault("1", "fail", "备注为空");
				}
			}

			// 查询是否已存在状态
			// 执行SQL
			SqlRowSet row = null;
			List<Object> quick = new ArrayList<Object>();
			quick.add(sq_create_time);
			try {
				row = baseDao.queryForRowSet("SELECT\n" +
						"\tMAX(sq.res_type) res_type\n" +
						"FROM\n" +
						"\t`socity_quick` sq\n" +
						"WHERE\n" +
						"\tsq.process_id = ?",quick.toArray());
			} catch (Exception e) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				logger.info("进入ResidencePermitService.uploadMaterial()方法.错误原因:"+ ExceptionDetailMessage.getExceptionDetail(e));
				return ResultMap.creatReault("7", "fail", "系统异常");
			}
			if (row.next()) {// 有记录
				String createTime = quickCreateTime;// 创建时间
				Integer resType = row.getInt("res_type");// 处理结果：1提交材料 2资料有误 3资料正确 4发送上门短信通知 5上门审核后失败（不在家） 6上门审核后成功 7已发放 8上门审核后失败（在家）
				// 根据状态插入数据或返回提示信息
				if (null != resType) {
					switch (resType) {
						case 2 :
							return update(sq_create_time,dweller_id,bizz_id,res_id,res_num,res_type,res_rule,res_url,stamp,version,visit_plat,visit_type,note,is_used,createTime,resTypeArray);
						case 1 :// 资料已提交成功,不允许再传
						case 3 :
						case 4 :
						case 5 :
						case 6 :
							return ResultMap.creatReault("4", "fail", "您提交的资料已通过审核,不允许重复提交,请耐心等待通知");
						case 7 : // 1.一个业务流程终结结束 - 正常终结（发证）
						case 8 : // 2.一个业务流程终结结束 - 异常终结（上门审核失败 - 在家的情况下）
						default :// 3.无记录则插入
							return insert(stamp,dep_id,version,visit_plat,visit_type,is_used,dweller_id,bizz_id,res_type_quick,res_note,sq_create_time,res_id,res_num,res_type,res_rule,res_url,note,resTypeArray);
					}
				}
			}
			// 无记录则插入
			return insert(stamp,dep_id,version,visit_plat,visit_type,is_used,dweller_id,bizz_id,res_type_quick,res_note,sq_create_time,res_id,res_num,res_type,res_rule,res_url,note,resTypeArray);
		} else {
			logger.info("进入ResidencePermitService.uploadMaterial()方法.错误原因:入参为空");
			return ResultMap.creatReault("1", "fail", "入参为空");
		}
	}
	
	// 插入数据
	public LinkedHashMap<Object, Object> insert(Long stamp, String dep_id, Integer version,Integer visit_plat,Integer visit_type,Integer is_used,String dweller_id,String bizz_id,Integer res_type_quick,String res_note, String sq_create_time,String res_id,Integer res_num,Integer res_type,String res_rule,String res_url,String note, JSONArray resTypeArray) {
		
		// 根据传入的部门id查出所有员工id,并随机分配
		String officer_id = null;
		List<Map<String, Object>> list = baseDao.queryForList("SELECT od.officer_id FROM officer_department od WHERE od.dep_id=?", dep_id);
		if (null != list) { // 有记录
			if (list.size() == 1) {
				officer_id = (String) list.get(0).get("officer_id");
			}
			if (list.size() > 0) {
				Integer num = (int) Math.round(Math.random() * list.size());
				if (num == 0) {
					officer_id = (String) list.get(num).get("officer_id");
				} else {
					officer_id = (String) list.get(num - 1).get("officer_id");
				}
			}
		} else if (list.size() == 0){// 无记录
			logger.info("进入ResidencePermitService.uploadMaterial()=>insert()方法.错误原因:没有获取到员工id,无法进行任务分配");
			return ResultMap.creatReault("5", "fail", "您传入的部门下没有获取到员工id,无法进行任务分配");
		}
		
		// 插入数据
		String create_time = DateUtil.format(new Date(stamp),"yyyy-MM-dd HH:mm:dd"); // 创建时间yyyy-MM-dd HH:mm:ss
		String update_time = create_time; // 更新时间yyyy-MM-dd HH:mm:ss

		String process_id = UUID.randomUUID().toString().replace("-",""); // 流程唯一标识区分

		List<Object> quick = new ArrayList<Object>();
		quick.add(UUID.randomUUID().toString().replaceAll("-", ""));
		quick.add(dweller_id);
		quick.add(officer_id);
		quick.add(bizz_id);
		quick.add(res_type_quick);
		quick.add(res_note);
		quick.add(process_id);
		quick.add(create_time);
		quick.add(update_time);
		quick.add(stamp);
		quick.add(version);
		quick.add(visit_plat);
		quick.add(visit_type);
		quick.add(note);
		quick.add(is_used);

		StringBuilder sb=new StringBuilder("INSERT INTO socity_quick_resource VALUES\t");
		int size = resTypeArray.size();
		for (int i = 0; i < size; i++) {
			JSONObject obj = JSON.parseObject(resTypeArray.get(i).toString());
			String res_url1 = (String) obj.get("res_url");
			sb.append("('"+UUID.randomUUID().toString().replaceAll("-", "")+"','"+process_id+"','"+dweller_id+"','"+bizz_id+"','"+obj.get("res_id")+"',"+obj.get("res_num")+","+obj.get("res_type")+",'"+obj.get("res_rule")+"','"+res_url1+"','"+create_time+"','"+update_time+"',"+stamp+","+version+","+visit_plat+","+visit_type+",'"+obj.get("note")+"',"+is_used+")");
			if (i < size-1) {
				sb.append(",");
			}
		}
		
		// 执行SQL
		int insertRecord = 0;
		try {
			insertRecord = baseDao.update("INSERT INTO socity_quick VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",quick.toArray());
			if (insertRecord <= 0) {// 插入失败
				logger.info("进入ResidencePermitService.uploadMaterial()=>insert()方法.错误原因:插入记录到socity_quick表失败");
				return ResultMap.creatReault("6", "fail", "插入记录失败");
			}
			insertRecord = baseDao.update(sb.toString());
			if (insertRecord < size) {// 插入失败
				logger.info("进入ResidencePermitService.uploadMaterial()=>insert()方法.错误原因:插入记录到socity_quick_resource表失败");
				return ResultMap.creatReault("9", "fail", "传入的数据没有全部插入成功");
			}
		} catch (Exception e) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			logger.info("进入ResidencePermitService.uploadMaterial()=>insert()方法.错误原因:"+ ExceptionDetailMessage.getExceptionDetail(e));
			return ResultMap.creatReault("7", "fail", "系统异常");
		}

		// 参数置空
		quick = null;
		sb = null;
		
		logger.info("进入ResidencePermitService.uploadMaterial()=>insert()方法.执行成功:数据插入成功");
		return ResultMap.creatReault("8", "success", "数据插入成功");
	}
	
	// 更新数据
	public LinkedHashMap<Object, Object> update(String sq_create_time,String dweller_id,String bizz_id,String res_id,Integer res_num,Integer res_type,String res_rule,String res_url,Long stamp,Integer version,Integer visit_plat,Integer visit_type,String note,Integer is_used,String createTime, JSONArray resTypeArray) {
		
		StringBuilder sb=new StringBuilder();
		int size = resTypeArray.size();
		for (int i = 0; i < size; i++) {
			JSONObject obj = JSON.parseObject(resTypeArray.get(i).toString());
			sb.append("UPDATE\n" +
						"socity_quick_resource\n" +
					"SET\n" +
						"\tdweller_id='"+dweller_id+"',\n" +
						"\tbizz_id='"+bizz_id+"',\n" +
						"\tres_id='"+obj.get("res_id")+"',\n" +
						"\tres_num="+obj.get("res_num")+",\n" +
						"\tres_type="+obj.get("res_type")+",\n" +
						"\tres_rule='"+obj.get("res_rule")+"',\n" +
						"\tres_url='"+obj.get("res_url")+"',\n" +
						"\tupdate_time='"+DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:dd")+"',\n" +
						"\tstamp='"+stamp+"',\n" +
						"\tversion="+version+",\n" +
						"\tvisit_plat="+visit_plat+",\n" +
						"\tvisit_type="+visit_type+",\n" +
						"\tnote='"+obj.get("note")+"',\n" +
						"\tis_used="+is_used+"\n" +
					"WHERE\n" +
						"\tsq_create_time='"+sq_create_time+"'\n" +
					"and res_id = '"+obj.get("res_id")+"'\n" +
					"and note= '"+obj.get("note")+"';\n");

			// 执行SQL
			int insertRecord = 0;
			try {
				insertRecord = baseDao.update(sb.toString());
				if (insertRecord < 1) {//更新失败
//				if (insertRecord < size) {//更新失败
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//任意一条更新失败,回滚
					logger.info("进入ResidencePermitService.uploadMaterial()=>update()方法.错误原因:更新记录到socity_quick_resource表失败");
					return ResultMap.creatReault( "9", "fail", "传入的数据没有全部更新记录成功");
				}
				sb.delete(0, sb.length()); // 清空
			} catch (Exception e) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				logger.info("进入ResidencePermitService.uploadMaterial()=>update()方法.错误原因:"+ ExceptionDetailMessage.getExceptionDetail(e));
				return ResultMap.creatReault("7", "fail", "系统异常");
			}
		}
		
//		// 执行SQL
//		int insertRecord = 0;
//		try {
//			insertRecord = baseDao.update(sb.toString());
//			if (insertRecord < size) {//更新失败
//				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//任意一条更新失败,回滚
//				logger.info("进入ResidencePermitService.uploadMaterial()=>update()方法.错误原因:更新记录到socity_quick_resource表失败");
//				return ResultMap.creatReault("9", "fail", "传入的数据没有全部更新记录成功");
//			}
//		} catch (Exception e) {
//			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//			logger.info("进入ResidencePermitService.uploadMaterial()=>update()方法.错误原因:"+ ExceptionDetailMessage.getExceptionDetail(e));
//			return ResultMap.creatReault("7", "fail", "系统异常");
//		}
		
		logger.info("进入ResidencePermitService.uploadMaterial()=>update()方法.执行成功:更新记录到socity_quick_resource表成功");
		return ResultMap.creatReault("10", "success", "数据更新成功");
	}

	/**
	 * 办事人员查询居住证办理业务接口，查询条件：身份证号 居民姓名（模糊）办理状态
	 * @author zl 2018年7月23日 下午8:35:19
	 * @param param
	 * @param request
	 * @return
	 */
	public Object residencePermitList(String param ,HttpServletRequest request) {
		
		if (StringUtils.isNoneBlank(StringUtils.trim(param))) {
			// 解析param
			JSONObject jsonObject = null;
			try {
				jsonObject = JSON.parseObject(param);
			} catch (JSONException e) {
				return ResultMap.creatReault("0", "fail", "参数格式有误");
			}

			//**********************************************************
			LinkedHashMap<Object, Object> map = null;

			String systoken = null;
			if (!(jsonObject.getInteger("visit_plat") != 0)) { // 网页端
				systoken = jsonObject.getString("systoken"); // 全局token
				if (StringUtils.isBlank(systoken)) {
					logger.info("systoken为空");
					map = ResultMap.creatReault("33", "失败", "token为空");
					logger.info("出去《办事人员查询居住证》residencePermitList()方法；出参 = " + JSON.toJSONString(map));
					return map;
				}
			}

			String officerId = null;
			if (jsonObject.getInteger("visit_plat") == 0) { // 网页端

				// 根据身份证从redis中获取token
				Jedis jedis = new Jedis("140.143.210.101", 6379);
				jedis.auth("q1w2e3r4t5");

				List<String> infoList = jedis.hmget(systoken, "systoken", "officerId");
				String systokenRedis = null;
				if (infoList != null && infoList.size() > 0) {
					systokenRedis = infoList.get(0); // token
					officerId = infoList.get(1); // 用户id
				}

				// 查看token是否过期
				if (StringUtils.isBlank(systokenRedis)) { // 重新登录，弹出登录框
					logger.info("全局systoken过期，需要重新获取systoken");
					map = ResultMap.creatReault("33", "失败", "systoken过期");
					logger.info("出去《办事人员查询居住证》residencePermitList()方法；出参 = " + JSON.toJSONString(map));
					return map;
				}

				// token不一致
				if (!StringUtils.equals(systokenRedis, systoken)) {
					logger.info("用户访问的token不一致");
					map = ResultMap.creatReault("331", "失败", "systoken不一致");
					logger.info("出去《办事人员查询居住证》residencePermitList()方法；出参 = " + JSON.toJSONString(map));
					return map;
				}

			}
			//**********************************************************
			
			String officer_id = (String) jsonObject.get("officer_id");// 办事员ID
			String offset = request.getParameter("offset");
			String limit = request.getParameter("limit");
			Integer start = null;// 分页起始位置
			Integer end = null;// 分页结束位置
			if (null == offset || "".equals(offset)) {
				return ResultMap.creatReault("1", "fail", "分页起始位置为空");
			} else {
				start = Integer.parseInt(offset);
			}
			if (null == limit || "".equals(limit)) {
				return ResultMap.creatReault("1", "fail", "分页结束位置为空");
			} else {
				end = Integer.parseInt(limit);
			}		
			String idNumber = (String) jsonObject.get("idNumber");// 身份证号码
			String dwellerName = (String) jsonObject.get("dwellerName");// 居民姓名
			Integer res_type = null;// 处理结果：1提交材料 2资料有误 3资料正确 4发送上门短信通知 5上门审核后失败（不在家） 6上门审核后成功 7已发放 8上门审核后失败（在家）
			if (null!=jsonObject.get("res_type")||!"".equals(jsonObject.get("res_type"))) {
				res_type = jsonObject.getInteger("res_type");
			}
			Long stamp = null; // 时间戳
			if (null!=stamp||!"".equals(jsonObject.get("stamp"))) {
				stamp = (Long) jsonObject.get("stamp");
			}
			Integer version = (Integer) jsonObject.get("version"); // 数据版本 0:测试 1:生产
			Integer visit_plat = (Integer) jsonObject.get("visit_plat"); // 访问平台 0网页 1一体机 2小程序 3其他
			Integer visit_type = (Integer) jsonObject.get("visit_type"); // 访问类型 0测试 1生产
			Integer is_used = (Integer) jsonObject.get("is_used"); // 是否失效 0:有效 1:无效
			
			// 入参判空
			if (null == stamp) {
				return ResultMap.creatReault("1", "fail", "时间戳为空");
			}
			if (null == officer_id || "".equals(officer_id)) {
				return ResultMap.creatReault("1", "fail", "办事员ID为空");
			}
			if (null == version) {
				return ResultMap.creatReault("1", "fail", "数据版本为空");
			}
			if (null == visit_type) {
				return ResultMap.creatReault("1", "fail", "访问类型为空");
			}
			if (null == is_used) {
				return ResultMap.creatReault("1", "fail", "是否失效为空");
			}

			// 获取结果集
			StringBuilder resultSql=new StringBuilder("SELECT\n" +
					"\tsq.process_id processId,\n" +
					"\tsq.ID quickId,\n" +
					"\tsq.dweller_id dwellerId,\n" +
					"\tsq.officer_id officerId,\n" +
					"\tsq.bizz_id,\n" +
					"\tsq.res_type quickResType,\n" +
					"\tsq.res_note quickResNote,\n" +
					"\tsq.create_time quickCreateTime,\n" +
					"\tsq.update_time updateTime,\n" +
					"\tdw.dweller_name dwellerName,\n" +
					"\tdw.dweller_idcard dwellerIdcard,\n" +
					"\toff.officer_name officerName,\n" +
					"\n" +
					"IF (\n" +
					"\t? = sq.officer_id,\n" +
					"\t0,\n" +
					"\t1\n" +
					") AS flag\n" +
					"FROM\n" +
					"\tsocity_quick sq,\n" +
					"\tdweller dw,\n" +
					"\tofficer off,\n" +
					"\t(\n" +
					"\t\tSELECT\n" +
					"\t\t\tMAX(sq2.res_type) maxResType,\n" +
					"\t\t\tsq2.process_id\n" +
					"\t\tFROM\n" +
					"\t\t\tsocity_quick sq2\n" +
					"\t\tGROUP BY\n" +
					"\t\t\tsq2.process_id\n" +
					"\t) max_res_type\n" +
					"WHERE\n" +
					"\tsq.version = ?\n" +
					"AND sq.visit_type = ?\n" +
					"AND sq.is_used = ?\n" +
					"AND sq.dweller_id = dw.ID\n" +
					"AND sq.officer_id = off.ID\n" +
					"AND sq.res_type = max_res_type.maxResType\n" +
					"AND sq.process_id = max_res_type.process_id\n" +
					"AND\n" +
					"IF (\n" +
					"\t? NOT IN (\n" +
					"\t\tSELECT\n" +
					"\t\t\toffr.officer_id\n" +
					"\t\tFROM\n" +
					"\t\t\tofficer_role offr\n" +
					"\t\tWHERE\n" +
					"\t\t\toffr.role_id IN (\n" +
					"\t\t\t\t'leader18f705d08db6479d8e14b8d11b'\n" +
					"\t\t\t)\n" +
					"\t),\n" +
					"\t(\n" +
					"\n" +
					"\t\tIF (\n" +
					"\t\t\t(\n" +
					"\t\t\t\t? IN (\n" +
					"\t\t\t\t\tSELECT\n" +
					"\t\t\t\t\t\tod.officer_id\n" +
					"\t\t\t\t\tFROM\n" +
					"\t\t\t\t\t\tofficer_department od\n" +
					"\t\t\t\t\tWHERE\n" +
					"\t\t\t\t\t\tod.officer_id NOT IN (\n" +
					"\t\t\t\t\t\t\tSELECT DISTINCT\n" +
					"\t\t\t\t\t\t\t\todd.parent_id\n" +
					"\t\t\t\t\t\t\tFROM\n" +
					"\t\t\t\t\t\t\t\tofficer_department odd\n" +
					"\t\t\t\t\t\t)\n" +
					"\t\t\t\t)\n" +
					"\t\t\t),\n" +
					"\t\t\t(\n" +
					"\t\t\t\tsq.officer_id = ?\n" +
					"\t\t\t),\n" +
					"\t\t\t(\n" +
					"\t\t\t\tsq.officer_id IN (\n" +
					"\t\t\t\t\tSELECT\n" +
					"\t\t\t\t\t\tod.officer_id\n" +
					"\t\t\t\t\tFROM\n" +
					"\t\t\t\t\t\tofficer_department od\n" +
					"\t\t\t\t\tWHERE\n" +
					"\t\t\t\t\t\tod.parent_id = ?\n" +
					"\t\t\t\t)\n" +
					"\t\t\t)\n" +
					"\t\t)\n" +
					"\t),\n" +
					"\t(1 = 1)\n" +
					")\n");

			// 条件参数
			List<Object> quick = new ArrayList<Object>();
			quick.add(officer_id);

			quick.add(version);
			quick.add(visit_type);
			quick.add(is_used);

			quick.add(officer_id);
			quick.add(officer_id);
			quick.add(officer_id);
			quick.add(officer_id);

			// 查询条件：身份证号  居民姓名（模糊）办理状态
			if (null != idNumber && !"".equals(idNumber)) {

				resultSql.append("AND dw.dweller_idcard=?\r\n");
				
				quick.add(idNumber);
			}
			if (null != dwellerName && !"".equals(dwellerName)) {

				resultSql.append("AND dw.dweller_name LIKE ?\r\n");
				
				quick.add("%"+dwellerName+"%");
			}
			if (null != res_type) {

				resultSql.append("AND sq.res_type=?\r\n");
				
				quick.add(res_type);
			}

			resultSql.append("GROUP BY\n" +
					"\tsq.process_id\n");

			// 获取总数
			StringBuilder getCountSql=new StringBuilder("SELECT count(*) as count from ("+resultSql+") as list");

			// 总记录数
	        long count = 0;
	        try {
	            count = baseDao.getCount(getCountSql.toString(), quick);
	        } catch (Exception e) {
	        	logger.info("进入ResidencePermitService.residencePermitList()方法.错误原因:"+ ExceptionDetailMessage.getExceptionDetail(e));
	        	return ResultMap.creatReault("7", "fail", "系统异常");
	        }
	        
	        // 分页条件
	        resultSql.append("LIMIT ?,?");
	        quick.add(start);
			quick.add(end);
			
			// 结果集,0 能修改,1不能修改
	        List<Map<String, Object>> list = null;
			try {
				list = baseDao.queryForList(resultSql.toString(), quick.toArray());
			} catch (Exception e) {
				logger.info("进入ResidencePermitService.residencePermitList()方法.错误原因:"+ ExceptionDetailMessage.getExceptionDetail(e));
				return ResultMap.creatReault("7", "fail", "系统异常");
			}

			quick = null;
			
			map = ResultMap.creatReault("4","success", list);
			map.put("total", count);
			return map;
		} else {
			return ResultMap.creatReault("1", "fail", "参数为空");
		}
	}

	/**
	 * 办事人员查询居住证办理详细信息
	 * @author zl 2018年7月25日 下午12:12:57
	 * @param param
	 * @param request
	 * @return
	 */
	public Object residencePermitDetail(String param ,HttpServletRequest request) {
		
		if (StringUtils.isNoneBlank(StringUtils.trim(param))) {
			// 解析param
			JSONObject jsonObject = null;
			try {
				jsonObject = JSON.parseObject(param);
			} catch (JSONException e) {
				return ResultMap.creatReault("0", "fail", "参数格式有误");
			}

			String dweller_id = jsonObject.getString("dweller_id");// 居民ID
			String processId = jsonObject.getString("processId");// 流程唯一标识
			Long stamp = null; // 时间戳
			if (null!=stamp||!"".equals(jsonObject.get("stamp"))) {
				stamp = jsonObject.getLong("stamp");
			}
			Integer version = jsonObject.getInteger("version"); // 数据版本 0:测试 1:生产
			Integer visit_plat = jsonObject.getInteger("visit_plat"); // 访问平台 0网页 1一体机 2小程序 3其他
			Integer visit_type = jsonObject.getInteger("visit_type"); // 访问类型 0测试 1生产
			Integer is_used = jsonObject.getInteger("is_used"); // 是否失效 0:有效 1:无效
			
			// 入参判空
			if (null == dweller_id || "".equals(dweller_id)) {
				return ResultMap.creatReault("1", "fail", "居民ID为空");
			}
			if (null == processId || "".equals(processId)) {
				return ResultMap.creatReault("1", "fail", "流程唯一标识为空");
			}
			if (null == stamp) {
				return ResultMap.creatReault("1", "fail", "时间戳为空");
			}
			if (null == version) {
				return ResultMap.creatReault("1", "fail", "数据版本为空");
			}
			if (null == visit_plat) {
				return ResultMap.creatReault("1", "fail", "访问平台为空");
			}
			if (null == visit_type) {
				return ResultMap.creatReault("1", "fail", "访问类型为空");
			}
			if (null == is_used) {
				return ResultMap.creatReault("1", "fail", "是否失效为空");
			}

			//**********************************************************
			LinkedHashMap<Object, Object> map = null;

			String systoken = null;
			if (!(jsonObject.getInteger("visit_plat") != 0)) { // 网页端
				systoken = jsonObject.getString("systoken"); // 全局token
				if (StringUtils.isBlank(systoken)) {
					logger.info("systoken为空");
					map = ResultMap.creatReault("33", "失败", "token为空");
					logger.info("出去《办事人员查询居住证办理详细信息》residencePermitDetail()方法；出参 = " + JSON.toJSONString(map));
					return map;
				}
			}

			String officerId = null;
			if (jsonObject.getInteger("visit_plat") == 0) { // 网页端

				// 根据身份证从redis中获取token
				Jedis jedis = new Jedis("140.143.210.101", 6379);
				jedis.auth("q1w2e3r4t5");

				List<String> infoList = jedis.hmget(systoken, "systoken", "officerId");
				String systokenRedis = null;
				if (infoList != null && infoList.size() > 0) {
					systokenRedis = infoList.get(0); // token
					officerId = infoList.get(1); // 用户id
				}

				// 查看token是否过期
				if (StringUtils.isBlank(systokenRedis)) { // 重新登录，弹出登录框
					logger.info("全局systoken过期，需要重新获取systoken");
					map = ResultMap.creatReault("33", "失败", "systoken过期");
					logger.info("出去《办事人员查询居住证办理详细信息》residencePermitDetail()方法；出参 = " + JSON.toJSONString(map));
					return map;
				}

				// token不一致
				if (!StringUtils.equals(systokenRedis, systoken)) {
					logger.info("用户访问的token不一致");
					map = ResultMap.creatReault("331", "失败", "systoken不一致");
					logger.info("出去《办事人员查询居住证办理详细信息》residencePermitDetail()方法；出参 = " + JSON.toJSONString(map));
					return map;
				}

			}
			//**********************************************************
			
			StringBuilder sql=new StringBuilder("SELECT sqr.sq_create_time,sqr.dweller_id,sqr.bizz_id,sqr.res_id,res.res_name,sqr.res_num,sqr.res_type,sqr.res_rule,sqr.res_url,sqr.create_time,sqr.update_time,sqr.is_used,sqr.note\r\n" +
					"FROM socity_quick_resource sqr,resource res\r\n" + 
					"WHERE\r\n" + 
					"sqr.res_id=res.ID\r\n" + 
					"AND sqr.dweller_id=?\r\n" + 
					"AND sqr.sq_create_time=?\r\n" +
					"AND sqr.version=?\r\n" + 
					"AND sqr.visit_type=?\r\n" + 
					"AND sqr.is_used=?\r\n");

			List<Object> condition = new ArrayList<Object>();
			condition.add(dweller_id);
			condition.add(processId);
			condition.add(version);
			condition.add(visit_type);
			condition.add(is_used);

			List<Map<String, Object>> list = null;
			try {
				list = baseDao.queryForList(sql.toString(), condition.toArray());
			} catch (Exception e) {
				logger.info("进入ResidencePermitService.residencePermitDetail()方法.错误原因:"+ ExceptionDetailMessage.getExceptionDetail(e));
				return ResultMap.creatReault("7", "fail", "系统异常");
			}
			
			return ResultMap.creatReault("1", "success", list);
		} else {
			return ResultMap.creatReault("1", "fail", "参数为空");
		}
	}
}
